
class EventBus1 {
  private events: {
    [key: string]: Array<{fn: Function; isOnce: boolean}>
  }
  constructor() {
    this.events = {}
  }
  on(type: string, fn: Function, isOnce: boolean = false) {
    const events = this.events
    if (events[type] == null) {
      events[type] = [] // 初始化 key 的 fn 数组
    }
    events[type].push({fn, isOnce})
  }
  once(type: string, fn: Function) {
    this.on(type, fn, true)
  }
  off(type: string, fn?: Function) {
    if (!fn) {
      // 解锁所有 type 的函数
      this.events[type] = []
    } else {
      // 解绑单个fn
      const fnList = this.events[type]
      if (fnList) {
        this.events[type] = fnList.filter(item => item.fn !== fn)
      }
    }
  }
  emit(type: string, ...args: any[]) {
    const fnList = this.events[type]
    if(fnList == null) return
    // 注意
    this.events[type] = fnList.filter(item => {
      const {fn, isOnce} = item
      fn(...args)
      // once执行一次就要被过滤掉
      if (!isOnce) return
      return false
    })
  }
}
/**
 * 拆分保存 on 和 once 事件
*/ 
class EventBus2 {
  private events: {
    [key: string]: Array<Function>
  }
  private onceEvents: {
    [key: string]: Array<Function>
  }
  constructor() {
    this.events = {}
  }
  on(type: string, fn: Function) {
    const events = this.events
    if (events[type] == null) events[type] = []
    events[type].push(fn)
  }
  once(type: string, fn: Function) {
    const onceEvents = this.onceEvents
    if (onceEvents[type] == null) onceEvents[type] = []
    onceEvents[type].push(fn)
  }
  off(type: string, fn: Function) {
    if (!fn) {
      // 解锁所有 type 的函数
      this.events[type] = []
    } else {
      // 解绑单个fn
      const fnList = this.events[type]
      const onceEvents = this.events[type]
      if (fnList) {
        this.events[type] = fnList.filter(curFn => curFn !== fn)
      }
      if (onceEvents) {
        this.events[type] = onceEvents.filter(curFn => curFn !== fn)
      }
    }
  }
  emit(type: string, ...args: any[]) {
    const fnList = this.events[type]
    const onceEvents = this.events[type]
    if(fnList) {
      fnList.forEach(f => f(...args))
    }
    if(onceEvents) {
      onceEvents.forEach(f => f(...args))
      // once执行一次就删除
      this.onceEvents[type] = []
    }
    
  }
}